import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class CalendarDemo {

    public static void main(String[] args) {
        JFrame frame = new JFrame("日历小程序");
        frame.setSize(400, 400);

        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        // 顶部的年月选择器
        JPanel top = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel yearLabel = new JLabel("年份");
        JComboBox<Integer> yearComboBox = new JComboBox<>();
        for (int i = 1900; i <= 2100; i++) {
            yearComboBox.addItem(i);
        }
        JLabel monthLabel = new JLabel("月份");
        JComboBox<Integer> monthComboBox = new JComboBox<>();
        for (int i = 1; i <= 12; i++) {
            monthComboBox.addItem(i);
        }
        JButton button = new JButton("确定");
        top.add(yearLabel);
        top.add(yearComboBox);
        top.add(monthLabel);
        top.add(monthComboBox);
        top.add(button);

        // 日历展示区
        JPanel center = new JPanel(new FlowLayout(FlowLayout.LEFT));

        // 绘制星期几标题栏，按照“123456日”的顺序排列
        String[] weekArray = {"1", "2", "3", "4", "5", "6", "日"};
        for (String week : weekArray) {
            JLabel label = new JLabel(week, JLabel.CENTER);
            label.setPreferredSize(new Dimension(50, 20)); // 设置标签大小
            center.add(label);
        }

        // 当前日期
        Date now = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        int currentYear = calendar.get(Calendar.YEAR);
        int currentMonth = calendar.get(Calendar.MONTH) + 1;

        // 初始化当前年月对应的日历
        showCalendar(center, currentYear, currentMonth, weekArray);

        // 监听事件，更新日历展示区
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int year = (int) yearComboBox.getSelectedItem();
                int month = (int) monthComboBox.getSelectedItem();
                showCalendar(center, year, month, weekArray);
            }
        });

        panel.add(top, BorderLayout.NORTH);
        panel.add(center, BorderLayout.CENTER);
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    /**
     * 显示指定年月的日历
     */
    private static void showCalendar(JPanel center, int year, int month, String[] weekArray) {
        // 清空日历展示区
        center.removeAll();

        // 绘制星期几标题栏，按照“123456日”的顺序排列
        for (String week : weekArray) {
            JLabel label = new JLabel(week, JLabel.CENTER);
            label.setPreferredSize(new Dimension(50, 20)); // 设置标签大小
            center.add(label);
        }

        // 计算该月第一天是星期几
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        int firstDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;

        // 根据星期一至星期日对应的日期，初始化Map
        Map<Integer, Integer> dayMap = new HashMap<>();
        dayMap.put(1, 2);
        dayMap.put(2, 3);
        dayMap.put(3, 4);
        dayMap.put(4, 5);
        dayMap.put(5, 6);
        dayMap.put(6, 7);
        dayMap.put(0, 1);

        // 初始化指定月份的日历
        int dayCount = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        for (int i = 1 - firstDayOfWeek; i <= dayCount; i++) {
            if (i <= 0) {
                center.add(new JLabel(""));
            } else {
                int dayOfWeek = dayMap.get(i % 7); // 计算当前日期是星期几
                JLabel dayLabel = new JLabel(Integer.toString(i), JLabel.CENTER);
                if (year == 2023 && month == 6 && i == 3) {
                    dayLabel.setForeground(Color.RED); // 设置特殊日期颜色为红色
                }
                dayLabel.setPreferredSize(new Dimension(50, 20)); // 设置标签大小
                center.add(dayLabel);
            }
        }

        // 刷新展示
        center.updateUI();
    }
}
